import pygtk
import gtk
import gobject
from gtk import gdk
from common import *


import Battlespace
import Grunt

class ViewportWidget(gtk.Widget):
    def __init__(self, viewport):
        gtk.Widget.__init__(self)
        self.viewport = viewport
        self.set_size_request(600, 600)
    def findPixelPos(self, coords):
        return coords.x * 10, coords.y * 10
    def findPixelRect(self, coords, tilesize=1):
        return coords.x * 10, self.allocation.height - (coords.y+1) * 10, tilesize * 10, tilesize * 10
    def find(self, (x,y)):
        for grunt in self.viewport.pullGrunts():
            pixelrect = self.findPixelRect(grunt.coords,1)
            ## if x, y within the pixelrect...
            if x >= pixelrect[0] and x <= pixelrect[0] + pixelrect[2] \
               and y >= pixelrect[1] and y <= pixelrect[1] + pixelrect[3]:
                return grunt
        return None
    def do_expose_event(self, event):
        ctx = self.window.cairo_create()
        
        for grunt in self.viewport.pullGrunts():
            ctx.set_source_color(gtk.gdk.color_parse(grunt.team.color))
            ctx.rectangle(*self.findPixelRect(grunt.coords,1))
            ctx.fill()
            if grunt.icon:
                self.window.draw_drawable(gc, self.pixmap, grunt.coords[0], grunt.coords[1])
        if self.viewport.selectedGrunt:
            ctx.set_source_color(gtk.gdk.color_parse("black"))
            ctx.rectangle(*self.findPixelRect(self.viewport.selectedGrunt.coords,1))
            ctx.stroke()
    def do_realize(self):
        # First set an internal flag telling that we're realized
        self.set_flags(self.flags() | gtk.REALIZED)
        self.window = gdk.Window(
            self.get_parent_window(),
            width=self.allocation.width,
            height=self.allocation.height,
            window_type=gdk.WINDOW_CHILD,
            wclass=gdk.INPUT_OUTPUT,
            event_mask=self.get_events() | gdk.EXPOSURE_MASK
            | gdk.BUTTON1_MOTION_MASK | gdk.BUTTON_PRESS_MASK
            | gtk.gdk.POINTER_MOTION_MASK
            | gtk.gdk.POINTER_MOTION_HINT_MASK)

        # Associate the gdk.Window with ourselves, Gtk+ needs a reference
        # between the widget and the gdk window
        self.window.set_user_data(self)

        self.style.attach(self.window)
        self.style.set_background(self.window, gtk.STATE_NORMAL)
        self.window.move_resize(*self.allocation)
        # load the star xpm
        self.gc = self.style.fg_gc[gtk.STATE_NORMAL]
    
gobject.type_register(ViewportWidget)

class Viewport:
    def __init__(self):
        self.frame = gtk.Frame()
        self.viewportwidget = ViewportWidget(self)
        viewportframe = gtk.Frame()
        viewportframe.shadow_type = gtk.SHADOW_ETCHED_IN
        viewportframe.add(self.viewportwidget)
        self.hbox = gtk.HBox()
        self.frame.add(self.hbox)
        self.leftbox = gtk.VBox()
        self.hbox.pack_start(self.leftbox, padding=5)
        self.toptext = gtk.TextBuffer()
        self.bottomtext = gtk.TextBuffer()
        self.toptextwidget = gtk.TextView(self.toptext)
        self.toptextwidget.set_size_request(100,100)
        self.toptextwidget.unset_flags(gtk.CAN_FOCUS)
        self.bottomtextwidget = gtk.TextView(self.bottomtext)
        self.bottomtextwidget.unset_flags(gtk.CAN_FOCUS)
        self.toptextwidget.sensitive = False
        assert isinstance(self.toptext, gtk.TextBuffer)
        self.toptext.sensitive = False
        #self.toptextwidget.style.bg = gtk.gdk.color_parse("grey")
        scroll1 = gtk.ScrolledWindow()
        scroll1.set_size_request(100,100)
        scroll1.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        scroll1.add_with_viewport(self.toptextwidget)
        scroll2 = gtk.ScrolledWindow()
        scroll2.set_size_request(150,100)
        scroll2.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        self.bottomtextwidget.set_size_request(150,50)
        scroll2.add_with_viewport(self.bottomtextwidget)
        
        self.leftbox.pack_start(scroll1, padding=5)
        self.leftbox.pack_start(scroll2, padding=5)
        self.hbox.pack_start(viewportframe)
        self.toptext.insert_at_cursor("Hi there")
        self.bottomtext.insert_at_cursor("Pal")
        self.viewportwidget.connect('button-press-event', self.viewport_clicked)
        self.selectedGrunt = None
        self.frame.set_flags(gtk.CAN_FOCUS)
        self.frame.connect('key-press-event', self.keyPressed)
    def pullGrunts(self):
        return self.battlespace.gruntsWithin((0,0), 100, 100)
    def widget(self):
        return self.frame
    def draw_selected_grunt(self):
        if self.selectedGrunt:
            assert isinstance(self.selectedGrunt, Grunt.Grunt)
            self.toptext.set_text("Selected:\n"+self.selectedGrunt.infotext())
        else:
            self.toptext.set_text("")
        self.frame.queue_draw()
    def viewport_clicked(self, widget, event):
        # For now, happens on mouse-down. I know, this is egregious from a UI perspective.
        self.selectedGrunt = self.viewportwidget.find((event.x, event.y))
        self.draw_selected_grunt()
    def keyPressed(self, widget, event):
        if event.keyval == 32:
            self.battlespace.execute()
        self.draw_selected_grunt()
        self.frame.queue_draw()
        
if __name__ == "__main__":
    b = Battlespace.Battlespace()
    Battlespace.testSetup(b)
    v = Viewport()
    v.battlespace = b
    win = gtk.Window()
    win.connect('delete-event', gtk.main_quit)
    win.add(v.widget())
    win.show_all()    
    gtk.main() 
    
    
    